﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BrokerBase.Lib.Person;
using BrokerBase.Lib.Product;

namespace BrokerBase.Lib.Policy
{
    public class Scheme:IScheme
    {
        public Scheme()
        {
            //Policies = new List<IPolicy>();
            PolicyLights = new List<IPolicyLight>();
            PlanPayPeriods = new List<IPlanPayPeriod>();
        }

        public virtual string Number { get; set; }

        public virtual int PeriodRange { get; set; }

        public virtual DateTime BizDate { get; set; }

        public virtual DateTime CreateDate { get; set; }

        public virtual IPerson Holder{get;set;}

        public virtual IPerson Insurant{get;set;}

        /// <summary>
        /// 投保人性别
        /// </summary>
        public virtual SexType HolderSex { get; set; }
        /// <summary>
        /// 投保人年龄
        /// </summary>
        public virtual int HolderAge { get; set; }
        /// <summary>
        /// 被保人性别
        /// </summary>
        public virtual SexType InsurantSex { get; set; }
        /// <summary>
        /// 被保人年龄
        /// </summary>
        public virtual int InsurantAge { get; set; }


        public virtual IPerson Beneficiary { get; set; }

        public virtual IList<IPolicy> Policies
        {
            get
            {
                IList<IPolicy> tmp = PolicyLights.Where(p => p.Policy != null).Select(q => q.Policy).ToList<IPolicy>();

                return PolicyLights.Where(p => p.Policy != null).Select(q => q.Policy).ToList<IPolicy>();
            }
        }


        public virtual IPolicy GetPolicy(string name)
        {
            return Policies.FirstOrDefault(p => p.Product.Name == name);
        }

        public virtual IPolicy BasicPolicy
        {
            get
            {

                IPolicy policy=Policies.FirstOrDefault(p => p.ProductType == ProductType.Basic);
                
                return policy;
            }
        }

        public virtual int Id { get; set; }

        public virtual int GetPeriodCount(int defaultMaxAge)
        {
            if (BasicPolicy.SelectedInsurancePeriod.Style == InsurancePeriodStyle.Lifetime)
            {
                return defaultMaxAge - this.InsurantAge + 1;
            }
            else
            {
                return BasicPolicy.InsurancePeriodLength;
            }

            //return BasicPolicy.InsurancePeriodLength > defaultMaxAge ? defaultMaxAge : BasicPolicy.InsurancePeriodLength;
        }

        public virtual DateTime? CheckTime { get; set; }

        public virtual string CheckerName { get; set; }

        public virtual bool IsCheck
        {
            get {return CheckTime == null ? false : true; }
        }

        public virtual double Fee { get { return PolicyLights.Where(q=>q.IsVerify).Sum(p => p.Fee); } }

        public virtual IList<IPlanPayPeriod> PlanPayPeriods { get; set; }

        public virtual void CalcPayPeriods()
        {
            PlanPayPeriods.Clear();
            DateTime beginTime = new DateTime(BizDate.Year, BizDate.Month, BizDate.Day);

            DateTime endTime = beginTime;

            //endTime = beginTime.AddYears(Policies[0].PaymentPeriodLength-1);
            endTime = beginTime.AddYears(BasicPolicyLight.PaymentPeriodLength -1);
            DateTime payTime = beginTime;

            int SerialNo = 0;

            while (payTime <= endTime)
            {
                IPlanPayPeriod pp = new PlanPayPeriod();
                pp.Scheme = this;
                pp.SerialNo = ++SerialNo;
                pp.PayTime = payTime;

                double tf = 0D;

                foreach (IPolicyLight pl in PolicyLights)
                {
                    if (payTime <= beginTime.AddYears(pl.PaymentPeriodLength - 1))
                    {
                        tf += pl.Fee;
                    }
                }

                pp.Fee = tf;
                PlanPayPeriods.Add(pp);

                payTime = payTime.AddMonths((int)(12 /this.BasicPolicyLight.SelectedTimeUnit.Coefficient));
            }
        }

        public virtual IList<IPolicyLight> PolicyLights { get; set; }

        public virtual IPolicyLight BasicPolicyLight 
        {
            get
            {
                IPolicyLight pl = PolicyLights.FirstOrDefault(p => p.ProductType == ProductType.Basic);
                return pl;
            }
        }

        //public virtual int GetInsurantAge()
        //{
        //    return Insurant.GetAgeByYear(BizDate);
        //}

        //public virtual int GetHolderAge()
        //{
        //    return Holder.GetAgeByYear(BizDate);
        //}

        public virtual int MaxProtectPeriod {
            get
            {
                if (this.PolicyLights.Where(a=>a.IsVerify).Count()>0)
                    return this.PolicyLights.Where(q=>q.IsVerify).Max(p => p.InsurancePeriodLength);
                else
                    return 0;

            }
        }

        public virtual int MaxPaymentPeriod 
        {
            get
            {
                if (this.PolicyLights.Where(a => a.IsVerify).Count() > 0)
                    return this.PolicyLights.Where(q=>q.IsVerify).Max(p => p.PaymentPeriodLength);
                else
                    return 0;
            }
        }

       public virtual string Description { get; set; }
    }
}
